<?php

namespace paper\http\response;

abstract class Response
{
    protected int $code;
    protected mixed $data;
    protected array $header = [];
    protected mixed $parameters;
    protected string $charset = "utf-8";

    public const CONTENT_TYPE_HTML = 'text/html';
    public const CONTENT_TYPE_JSON = 'application/json';


    public function __construct($data = '', int $code = 200, array $header = [], $parameters = null)
    {
        $this->data = $data;
        $this->code = $code;
        $this->header = array_merge($this->header, $header);
        $this->parameters = $parameters;
    }

    /**
     * @return mixed
     */
    public function getParameters()
    {
        return $this->parameters;
    }


    /**
     * @param string $charset
     */
    public function setCharset(string $charset): void
    {
        $this->charset = $charset;
    }

    /**
     * @param mixed $parameters
     */
    public function setParameters($parameters): void
    {
        $this->parameters = $parameters;
    }


    public function send()
    {

        /**
         * 获取输出的内容，基本上输出内容都是字符串
         */

        $data = $this->output($this->data);

        /**
         * headers_sent 函数用于检测是否已经发送了header头
         * 如果已经发送过header头说明已经有内容刷出，则无法再次发送header头
         * 主要针对在控制器中已经echo的情况
         */
        if (!headers_sent()) {
            http_response_code($this->code);
            $this->header['Content-Type'] = $this->contentType() . ';charset=' . $this->charset;
            foreach ($this->header as $key => $value) {
                header($key . (!is_null($value) ? ':' . $value : ''));
            }
        }
        $this->sendData($data);

//        if (config('trace'))
//            $this->app->trace->inject($this);

        if (function_exists('fastcgi_finish_request')) {
            // 提高页面响应
            fastcgi_finish_request();
        }
    }


    /**
     * @param array $header
     * @return Response
     */
    public function setHeader(array $header)
    {
        $this->header = array_merge($this->header, $this->header);
        return $this;
    }


    abstract protected function contentType(): string;

    abstract protected function output($data);

    protected function sendData($data)
    {
        echo $data;
    }

}